#include "stdafx.h"
#include "CC_TrayIcon.h"

CC_TrayIcon::CC_TrayIcon(HWND hWnd, UINT uID, UINT nNotifyMsg, UINT hIconID, LPCTSTR lpTip)
{
	if (!hIconID)
		return;

	HICON hIcon = AfxGetApp()->LoadIcon(hIconID);
	if (!hIcon)
		return;

	m_bVisibled = FALSE;
	m_uTrayNotifyMsg = nNotifyMsg;
	memset(&m_nidata, 0, sizeof(m_nidata));
	m_nidata.cbSize = sizeof(m_nidata);
	m_nidata.uID = uID;
	m_nidata.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
	m_nidata.uCallbackMessage = m_uTrayNotifyMsg;
	m_nidata.hIcon = hIcon;
	if (lpTip)
		_tcsncpy(m_nidata.szTip, lpTip, sizeof(m_nidata.szTip) / sizeof(TCHAR));
	else
		m_nidata.szTip[0] = _T('\0');
	m_nidata.hWnd = hWnd;
	DestroyIcon(hIcon);
}

CC_TrayIcon::~CC_TrayIcon()
{
	HideIcon();
}

BOOL CC_TrayIcon::ShowIcon()
{
	if (!m_bVisibled)
	{
		m_bVisibled = Shell_NotifyIcon(NIM_ADD, &m_nidata);
	}
	return m_bVisibled;
}

BOOL CC_TrayIcon::HideIcon()
{
	if (m_bVisibled)
	{
		m_bVisibled = !Shell_NotifyIcon(NIM_DELETE, &m_nidata);
	}
	return !m_bVisibled;
}

BOOL CC_TrayIcon::SetIcon(UINT hNewIconID)
{
	HICON hIcon = AfxGetApp()->LoadIcon(hNewIconID);
	if (!hIcon)
		return FALSE;
	m_nidata.hIcon = hIcon;
	if (m_bVisibled)
	{
		BOOL bRet;
		bRet = Shell_NotifyIcon(NIM_MODIFY, &m_nidata);
		DestroyIcon(hIcon);
		return bRet;
	}

	DestroyIcon(hIcon);
	return TRUE;
}

void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime)
{
	if (nTimerid != ID_TIMER_SWITCH_TRAYICON)
		return;

	// restore
	::SendMessage(hWnd, WM_MSG_TRAY_ICONSWITCH, 0, 0);
}

void CC_TrayIcon::SwitchIcon(UINT hNewIconID)
{
	HWND hWnd = ::AfxGetApp()->GetMainWnd()->GetSafeHwnd();
	if (!hWnd)
		return;

	SetIcon(hNewIconID);
	SetTimer(hWnd, ID_TIMER_SWITCH_TRAYICON, 100, TimerProc);
}

BOOL CC_TrayIcon::SetTipText(LPCTSTR lpNewTipText)
{
	memset(m_nidata.szTip, 0, sizeof(m_nidata.szTip));
	_tcsncpy(m_nidata.szTip, lpNewTipText, sizeof(m_nidata.szTip) / sizeof(TCHAR) - 1);
	if (m_bVisibled)
	{
		BOOL bRet;
		bRet = Shell_NotifyIcon(NIM_MODIFY, &m_nidata);
		return bRet;
	}
	else
		return TRUE;
}

BOOL CC_TrayIcon::IsVisibled()
{
	return m_bVisibled;
}

BOOL CC_TrayIcon::Rebuild()
{
	if (m_bVisibled)
	{
		Shell_NotifyIcon(NIM_DELETE, &m_nidata);
		m_bVisibled = FALSE;
		return ShowIcon();
	}
	else
		return TRUE;
}